package cn.lixin.user.service.impl;

import cn.lixin.basic.exception.BusinessException;
import cn.lixin.basic.service.impl.BaseServiceImpl;
import cn.lixin.basic.utils.MD5Utils;
import cn.lixin.basic.utils.StrUtils;
import cn.lixin.user.contain.UserConstants;
import cn.lixin.user.domain.Logininfo;
import cn.lixin.user.domain.User;
import cn.lixin.user.domain.UserDto;
import cn.lixin.user.mapper.LogininfoMapper;
import cn.lixin.user.mapper.UserMapper;
import cn.lixin.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LogininfoMapper logininfoMapper;


    @Override
    public User loadByPhone(String phone) {
        return userMapper.loadByPhone(phone);
    }

    /**
     * 手机注册
     * @param userDto
     */
    @Override
    public void register(UserDto userDto) {
        /*
         * 校验 ： 1 所有字段不能为空
         */
        String phone = userDto.getPhone();
        if (userDto.getConfirmPwd() == null || userDto.getPassword() == null ||
                phone == null || userDto.getVerifyCode() == null ) {
            throw new BusinessException("信息没有填写完整");
        }
        // 2 两次密码必须相同
        if (!userDto.getConfirmPwd().equals(userDto.getPassword())) {
            throw  new BusinessException("两次密码输入不相同");
        }
        // 3 用户是否被注册
        if (userMapper.loadByPhone(phone) != null){
            throw new BusinessException("已注册，请直接登录");

        }
        // 4 验证码是否相同
        Object codeTemp = redisTemplate.opsForValue().get(UserConstants.BUSINESS_REGISTER_PREFIX + phone);  // 根据redis中的key获取
        String verifyCode = codeTemp.toString().split(":")[0];// 从redis中拿到的验证码
        if (codeTemp == null){ // 没有通过手机号拿到验证码：
            throw new BusinessException("验证码失效");
        }
        if (!verifyCode.equalsIgnoreCase((userDto.getVerifyCode()))){
            throw new BusinessException("验证码错误");

        }

        /*
            业务：保存
         */
        User user = userDto2User(userDto);// 登录的userDto保存给user
        Logininfo logininfo = user2Logininfo(user);// user保存给logininfo
        logininfoMapper.save(logininfo); // 先保存到logininfo，因为user需要logininfo_id 这里是保存自增id
        user.setLogininfo_id(logininfo.getId()); // 重置一下logininfo信息
        userMapper.save(user);// 保存到user
    }

    @Override
    public User queryByLogininfoId(Long currentLoginInfoId) {
        return userMapper.queryByLogininfoId(currentLoginInfoId);
    }

    private Logininfo user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo); // 将user信息copy到logininfo
        logininfo.setType(1);
        return logininfo;
    }

    private User userDto2User(UserDto userDto) {
        User user = new User();
        user.setUsername(userDto.getPhone());
        user.setPhone(userDto.getPhone());

        String salt = StrUtils.getComplexRandomString(32);// 32位随机数
        String md5Pwd = MD5Utils.encrypByMd5(userDto.getPassword() + salt); //md5加密：加密密码和盐值组成

        user.setSalt(salt);
        user.setPassword(md5Pwd);
        return user;
    }

    @Override
    public void save(User user) {
        Logininfo logininfo = initUser(user);
        logininfoMapper.save(logininfo);
        user.setLogininfo_id(logininfo.getId());
        userMapper.save(user);
    }

    private Logininfo initUser(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        logininfo.setType(1);
        return logininfo;
    }

    @Override
    public void remove(Long id) {
        Logininfo logininfo = logininfoMapper.loadByUserId(id);
        logininfoMapper.remove(logininfo.getId());
        super.remove(id);
    }

    @Override
    public void update(User user) {
//        Logininfo logininfo = logininfoMapper.loadByUserId(user.getId());
        super.update(user);

    }
}
